package com.gl.order.security.filter;

import cn.hutool.core.util.StrUtil;
import com.gl.order.commom.ResultBean;
import com.gl.order.commom.excetion.ServiceExcetion;
import com.gl.order.commom.util.JwtTokenUtils;
import com.gl.order.commom.util.ResponseUtils;
import com.gl.order.config.JwtConfig;
import com.gl.order.security.model.SecurityUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;

/**
 * @Author: liangSY
 * @Date: 2021/6/8 10:08
 * jwt权限过滤器，验证权限是否合法
 */
@Slf4j
public class TokenAuthenticationFilter extends BasicAuthenticationFilter {


    public TokenAuthenticationFilter(AuthenticationManager authManager) {
        super(authManager);
    }


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 获取当前认证成功的用户权限信息
        UsernamePasswordAuthenticationToken authResult = getAuthentication(request,response);
        // 判断如果有权限信息，放到权限的上下文中
        if(authResult != null){
            SecurityContextHolder.getContext().setAuthentication(authResult);
        }
        chain.doFilter(request,response);
    }

    private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request,HttpServletResponse response) {
        // 获取Token字符串，token 置于 header 里
        String token = request.getHeader(JwtConfig.tokenHeader);
        if (StrUtil.isNotBlank(token)) {
            token = token.substring(JwtConfig.tokenPrefix.length()+1);
            if(!JwtTokenUtils.verifyToken(token)){
                log.info("current token is failure {}");
                return null;
            }
            if(!JwtTokenUtils.isLoginOfKey(token)){
                log.info("current token is failure");
                return null;
            }
            // 从Token中解密获取用户名
            SecurityUser securityUser = JwtTokenUtils.getUserInfo(token);
            String cachUserToken = JwtTokenUtils.timedCache.get(securityUser.getCurrentUserInfo().getId());
            if(!Objects.equals(token,cachUserToken)){
                return null;
            }

            return new UsernamePasswordAuthenticationToken(securityUser, token, securityUser.getAuthorities());
        }
        return null;
    }
}
